#include	"GameApp.h"
#include	"core/Cache.h"
#include	"network/LogConnector.h"
#include	"network/CenterConnector.h"
#include	"network/GameService.h"
#include	"utils/NameFilter.h"
#include	"utils/TextFilter.h"

#include	<DateTime.h>
#include	<IniFile.h>
#include	<Json.h>
#include	<Logger.h>
#include	<Path.h>
#include	<Script.h>
#include	<Utils.h>

bool GameApp::OnInit(Command & cmd) {
	IniFile conf;
	if (!conf.Load("config.ini")) throw std::runtime_error("failed to load config.ini");

	int log_level = conf.Get<int>("game", "log_level", ELog::Info);
	Logger::Instance().Init("game", "logs", 4194304, (ELog::Level)log_level);

	if (!TextFilter::Instance().Initialize()) {
		return false;
	} else if (!NameFilter::Instance().Initialize()) {
		return false;
	}

	std::string redis_ip = conf.Get<std::string>("redis", "ip", "127.0.0.1");
	int redis_port = conf.Get<int>("redis", "port", 6379);
	if (!GCache.Initialize(redis_ip, redis_port)) {
		LOG_ERR("Failed to connect to Redis[%s:%d]", redis_ip.c_str(), redis_port);
		return false;
	}

	std::string log_ip = conf.Get<std::string>("logserver", "ip", "127.0.0.1");
	int log_port = conf.Get<int>("logserver", "port", 10002);
	if (LogConnector::Instance().Connect(log_ip, log_port) != ENet::Success) {
		LOG_ERR("Failed to connect to logserver[%s:%d]", log_ip.c_str(), log_port);
		return false;
	}

	std::string listen_ip = conf.Get<std::string>("game", "ip", "127.0.0.1");
	int listen_port = conf.Get<int>("game", "port", 10010);
	if (GService.Initialize(listen_ip, listen_port) != ENet::Success) {
		LOG_ERR("Failed to listen on %s:%d", listen_ip.c_str(), listen_port);
		return false;
	}

	std::string center_ip = conf.Get<std::string>("center", "ip", "127.0.0.1");
	int center_port = conf.Get<int>("center", "port", 10003);
	if (GCenter.Connect(center_ip, center_port) != ENet::Success) {
		LOG_ERR("Failed to connect to center[%s:%d]", center_ip.c_str(), center_port);
		return false;
	}

	extern void RegisterLuaApi_File();
	extern void RegisterLuaApi_Misc();
	RegisterLuaApi_File();
	RegisterLuaApi_Misc();

	Path::Traverse("scripts/gs", [](const std::string & file) {
		if (file.size() <= 4) return;
		std::string ext = ToUpper(file.substr(file.size() - 4));
		if (ext == ".LUA") GLua.DoFile(file, true);
	});

	GLua.Call("Scheduler", "Start");

	LockFPS(20);
	LOG_INFO("Application game started ...");
	return true;
}

void GameApp::OnBreath() {
	GCache.Breath();

	GLua.Call("Timer", "Trigger");

	static int last_hms = 0;
	DateTime now;
	int hms = now.nHour * 10000 + now.nMin * 100 + now.nSec;
	if (last_hms != hms) {
		last_hms = hms;
		GLua.Call("Scheduler", "TimePoint", hms);
	}
}

void GameApp::OnExit(int code) {
	LOG_INFO("Application game will exit : %d", code);
}

RUN_APP(GameApp)